//
// Created by fazhehy on 2024/3/14.
//

#include "common_inc.h"

void beep_on()
{
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
}

void beep_off()
{
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);
}

void beep_toggle(uint16_t ms)
{
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
    HAL_Delay(ms);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);
    HAL_Delay(ms);
}

void motor_on(uint8_t dir)
{
    if (dir){
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET);
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_SET);
    }
    else{
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_RESET);
    }
}

void motor_off()
{
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_RESET);
}

int32_t get_battery_value()
{
    int32_t batteryVoltage = 0;
    HAL_ADC_Start(&hadc1);     //启动ADC转换

    for (uint8_t i = 0; i < 100; ++i) {
        HAL_ADC_PollForConversion(&hadc1, 50);
//        while (!HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC)) {
//
//        }
        batteryVoltage += HAL_ADC_GetValue(&hadc1);   //获取AD值
//        batteryVoltage += HAL_ADC_GetValue(&hadc1);
    }
    batteryVoltage /= 100;
    if (batteryVoltage >= 3327)
        return 99;
    if (batteryVoltage < 2825)
        return 0;
    batteryVoltage = (int32_t) (((float) (batteryVoltage - 2825) / (3327-2825)) * 100);
    return batteryVoltage;
}

void battery_display(int32_t percent)
{
    if (percent >= 99)
        percent = 99;
    if (percent <= 10)
    {
        for (int i = 0; i < 10; ++i) {
            beep_toggle(50);
        }
        percent = 0;
    }
    oled_show_num(84+25, 1, percent, 2);
    oled_show_char(84+26+2*6, 1, '%');
    oled_draw_round_rect(88, 0, 21, 10, 3);
    uint8_t w = 21*percent/100;
    if (w >= 6)
        oled_draw_fill_round_rect(88, 0, w, 10, 3);
}

void scene_display()
{
    oled_clear_buffer();
    HAL_ADCEx_Calibration_Start(&hadc1);
    battery_display(get_battery_value());
    oled_show_string(0, 0, "121 Dorm");
    oled_show_bmp(64-38, 32+3, name, 76, 24);
    oled_show_bmp(64-16, 6, fingerprint, 32, 32);
    oled_show_string(5, 56, "github.com/fazhehy");
    oled_update_screen();
}

uint8_t get_key_num()
{
    bool isLongPress = false;
    uint32_t tick;
    uint8_t keyNum = 0;
    if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_13) == GPIO_PIN_SET)
    {
        HAL_Delay(20);
        tick = HAL_GetTick();
        while (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_13) == GPIO_PIN_SET){
            if (HAL_GetTick() >= tick + 500){
                isLongPress = true;
            }
        }
        HAL_Delay(20);
        if (!isLongPress)
            keyNum = 2;
        else
            keyNum = 3;
    }
    return keyNum;
}

bool administratorFlag = false;

uint8_t main_task(uint8_t keyNum)
{
    uint8_t fingerNum;
    uint8_t state = fpm383c_get_fingerprint_num(&fingerNum);
    while (state != 0x00){
        HAL_Delay(200);
        state = fpm383c_get_fingerprint_num(&fingerNum);
    }
    oled_show_num(12*6, 56, fingerNum, 2);
    oled_show_string(0, 56, "finger num:");
    return keyNum;
}

uint8_t add_task(uint8_t keyNum)
{
    add_fingerprint();
    return 4;
}

uint8_t clear_task(uint8_t keyNum)
{
    fpm383c_clear_all();
    oled_clear_buffer();
    oled_show_string(0, 0, "administrator finger");
    oled_update_screen();
    add_fingerprint();
    oled_clear_buffer();
    oled_show_string(0, 0, "administrator finger");
    oled_update_screen();
    add_fingerprint();
    return 4;
}

uint8_t quit_task(uint8_t keyNum)
{
    administratorFlag = false;
    return 4;
}

void Main()
{
    oled_init();
    fpm383c_on();
    motor_off();
    uint16_t id = match_finger();
    if (id == 0xffff){
        fpm383c_control_led(red);
        oled_clear_buffer();
        oled_show_bmp(64-23, 0, middle_finger, 46, 64);
        oled_update_screen();
        beep_toggle(100);
        HAL_Delay(500);
    }
    else if (id == 0 || id == 1){
        menu_init();
        administratorFlag = true;
        for (;;){
            menu_task();
            if (!administratorFlag)
                break;
        }
    }
    else{
        fpm383c_control_led(green_blue);
        oled_clear_buffer();
        oled_show_bmp(64-18, 0, thumb, 39, 64);
        oled_update_screen();
        motor_on(0);
        beep_toggle(600);
        HAL_Delay(500);
        motor_off();
        HAL_Delay(1000);
        motor_on(1);
        HAL_Delay(1000);
    }
    motor_off();
    oled_clear_buffer();
    scene_display();
    uint8_t state;
    do {
        HAL_Delay(200);
        state = fpm383c_sleep();
    } while (state != 0x00);
    while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET);
    fpm383c_off();
    __HAL_RCC_PWR_CLK_ENABLE();
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
    HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
    HAL_PWR_EnterSTANDBYMode();
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    UNUSED(huart);
    if (huart->Instance == FPM383C_UART.Instance){
        fpm383c_callback();
    }
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    void SystemClock_Config(void);
    SystemClock_Config();
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
}
